﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace View
{
	public partial class ClipBoardForm : Form
	{

		IntPtr _ClipboardViewerNext;

		public ClipBoardForm()
		{
			InitializeComponent();
			RegisterClipboardViewer();
		}

		#region Events

		private void toolStripMenuItemClose_Click(object sender, EventArgs e)
		{
			this.clipBoardForm_Close(sender, e);
		}

		private void openMainFormToolStripMenuItem_Click(object sender, EventArgs e)
		{
            this.Show();
			this.WindowState = FormWindowState.Normal;

			//foreach(string s in Clipboard.GetFileDropList())
			//    this.label1.Text += "\n" + s;

			//this.label1.Text += "\n" + Clipboard.GetText();

		}

		private void minimizeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.WindowState = FormWindowState.Minimized;
            this.Hide();
		}

		private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SettingsForm settingsForm = new SettingsForm();
			settingsForm.ShowDialog();
		}

		private void notifyIconclip2tray_Click(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left)
			{
				if (this.WindowState == FormWindowState.Minimized)
				{
					openMainFormToolStripMenuItem_Click(sender, e);
				}
				else if (this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized)
				{
					minimizeToolStripMenuItem_Click(sender, e);
				}
			}
		
		}

		private void clipBoardForm_Close(object sender, EventArgs e)
		{
			//TODO Important Tasks(Logging) before closing 
			this.UnregisterClipboardViewer();
			Application.Exit();
		}

		private void ClipBoardForm_FormClosing(object sender, FormClosingEventArgs e)
		{
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                if (Properties.Settings.Default.minimizeMessageBox == true)
                {
                    DialogResult dr = MessageBox.Show("clip2Tray wird ins Tray minimiert.\nSoll diese Meldung zukünftig ausgeblendet werden?", "clip2tray - minimize to tray", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                    if (dr == DialogResult.Yes)
                    {
                        Properties.Settings.Default.minimizeMessageBox = false;
                        Properties.Settings.Default.Save();
                        this.minimizeToolStripMenuItem_Click(sender, e);
                    }
                    else if (dr == DialogResult.No)
                    {
                        this.minimizeToolStripMenuItem_Click(sender, e);
                    }
                    if (dr == DialogResult.Cancel)
                    {
                    }
                }
                else
                {
                    this.minimizeToolStripMenuItem_Click(sender, e);
                }
            }
            else if (e.CloseReason == CloseReason.ApplicationExitCall)
            {
                e.Cancel = false;
            }
		}

		private MarkedObjectView createMarkedObjectViewText(Image i, bool copy, bool selected, string info, string text)
		{
			MarkedObjectView mov = new MarkedObjectView(null, copy, selected, text, "Text");
			Point p = new Point(1, 10);
			return mov;
		}

		private MarkedObjectView createMarkedObjectViewFile(Image i, bool copy, bool selected, System.IO.FileInfo file)
		{
			MarkedObjectView mov = new MarkedObjectView(getAssociatedBitMap(file.FullName), copy, selected, file.FullName, "File/Directory - " + file.Name);
			Point p = new Point(1, 10); ;
			mov.Size = new Size(337, 68);
			mov.Location = p;
			return mov;
		}

		private void changeElementListing()
		{
			if (this.panelElements.Controls.Count > 1)
			{
				for (int i = 0; i < this.panelElements.Controls.Count - 1; i++)
				{
					Point p = new Point(1,
					this.panelElements.Controls[i].Location.Y + 70);

					this.panelElements.Controls[i].Location = p;
				}
			}
		}

		private Bitmap getAssociatedBitMap(string fileName)
		{
			if (fileName.Substring(fileName.Length - 5, 5).Contains('.'))
			{
				Icon retval = Icon.ExtractAssociatedIcon(fileName);
				return retval.ToBitmap();
			}
			else
			{
				return View.Properties.Resources.dir_64;
			}
		}

		private void createBallonTip(bool copy, System.IO.FileInfo fi)
		{
			System.Text.StringBuilder strBalloon = new System.Text.StringBuilder(100);

			if(copy)
				strBalloon.Append("copy\n" + fi.Name + "\n" + fi.Directory);
			else
				strBalloon.Append("cut\n" + fi.Name + "\n" + fi.Directory);

			this.notifyIconclip2tray.BalloonTipText = strBalloon.ToString();

			notifyIconclip2tray.BalloonTipIcon = ToolTipIcon.Info;
			this.notifyIconclip2tray.ShowBalloonTip(3000);
		}

		private void createBallonTip(bool copy, string s)
		{
			System.Text.StringBuilder strBalloon = new System.Text.StringBuilder(100);

			if (copy)
				strBalloon.Append("copy\n" + s);
			else
				strBalloon.Append("cut\n" + s);

			this.notifyIconclip2tray.BalloonTipText = strBalloon.ToString();

			notifyIconclip2tray.BalloonTipIcon = ToolTipIcon.Info;
			this.notifyIconclip2tray.ShowBalloonTip(3000);
		}
		#endregion

		#region ClipBoardViewerMethods

		private void RegisterClipboardViewer()
		{
			_ClipboardViewerNext = User32.SetClipboardViewer(this.Handle);
		}

		/// <summary>
		/// Remove this form from the Clipboard Viewer list
		/// </summary>
		private void UnregisterClipboardViewer()
		{
			User32.ChangeClipboardChain(this.Handle, _ClipboardViewerNext);
		}

		protected override void WndProc(ref Message m)
		{
			switch ((Msgs)m.Msg)
			{
				//
				// The WM_DRAWCLIPBOARD message is sent to the first window 
				// in the clipboard viewer chain when the content of the 
				// clipboard changes. This enables a clipboard viewer 
				// window to display the new content of the clipboard. 
				//
				case Msgs.WM_DRAWCLIPBOARD:


					GetClipboardData();

					//
					// Each window that receives the WM_DRAWCLIPBOARD message 
					// must call the SendMessage function to pass the message 
					// on to the next window in the clipboard viewer chain.
					//
					User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);
					break;


				//
				// The WM_CHANGECBCHAIN message is sent to the first window 
				// in the clipboard viewer chain when a window is being 
				// removed from the chain. 
				//
				case Msgs.WM_CHANGECBCHAIN:

					// When a clipboard viewer window receives the WM_CHANGECBCHAIN message, 
					// it should call the SendMessage function to pass the message to the 
					// next window in the chain, unless the next window is the window 
					// being removed. In this case, the clipboard viewer should save 
					// the handle specified by the lParam parameter as the next window in the chain. 

					//
					// wParam is the Handle to the window being removed from 
					// the clipboard viewer chain 
					// lParam is the Handle to the next window in the chain 
					// following the window being removed. 
					if (m.WParam == _ClipboardViewerNext)
					{
						//
						// If wParam is the next clipboard viewer then it
						// is being removed so update pointer to the next
						// window in the clipboard chain
						//
						_ClipboardViewerNext = m.LParam;
					}
					else
					{
						User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);
					}
					break;

				default:
					//
					// Let the form process the messages that we are
					// not interested in
					//
					base.WndProc(ref m);
					break;

			}
		}

		/// <summary>
		/// Show the clipboard contents in the window 
		/// and show the notification balloon if a link is found
		/// </summary>
		private void GetClipboardData()
		{
			//
			// Data on the clipboard uses the 
			// IDataObject interface
			//
			IDataObject iData = new DataObject();
			string strText = "clipmon";

			try
			{
				iData = Clipboard.GetDataObject();
			}
			catch (System.Runtime.InteropServices.ExternalException externEx)
			{
				// Copying a field definition in Access 2002 causes this sometimes?
				return;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				return;
			}
            
			// 
			// Get RTF if it is present
			//
			if (iData.GetDataPresent(DataFormats.Rtf))
			{
				//this.checkedListCopiedObjects.Items.Add((string)iData.GetData(DataFormats.Rtf));

				if (iData.GetDataPresent(DataFormats.Text))
				{
					strText = "RTF";
				}
			}
			else
			{
				// 
				// Get Text if it is present
				//
				if (iData.GetDataPresent(DataFormats.Text))
				{
					string s = (string)iData.GetData(DataFormats.Text);

					bool copy = true;
					bool selected = true;

					this.panelElements.Controls.Add(this.createMarkedObjectViewText(null, copy, selected, "Text", s));
					this.changeElementListing();

					this.createBallonTip(true, s);

					strText = "Text";
				}
				else if (iData.GetDataPresent(DataFormats.FileDrop))
				{
					string[] filePaths = (string[])iData.GetData(DataFormats.FileDrop);


					foreach (string s in filePaths)
					{
						//this.checkedListCopiedObjects.Items.Add(s);

						System.IO.FileInfo fi = new System.IO.FileInfo(s);

						bool copy = true;
						bool selected = true;
						
						//if (iData == DragDropEffects.Copy)
						//    copy = true;
						//if (iData == DragDropEffects.Move)
						//    cut = true;

						this.panelElements.Controls.Add(this.createMarkedObjectViewFile(null, copy, selected, fi));
						this.changeElementListing();

						this.createBallonTip(copy, fi);
					}
				}
				else
				{
					//
					// Only show RTF or TEXT
					//
					//this.labelCopiedObjects.Text += "\n(cannot display this format)";
				}
			}

			this.notifyIconclip2tray.BalloonTipTitle = "clip2tray";
		}

		#endregion

	}
}
